/*
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.util;

import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * collection层次结构的根接口。一个collection代表一组对象，称其为元素。
 * 一些集合允许重复元素，其他不允许。一些是有序的，其他的是无序的。
 * JDK没有提供任何直接实现这个接口的类：它提供更具体的子接口，像Set和List。
 * 这个接口通常用来传递集合，并在需要最大通用性的地方操纵它们。
 *
 * <p>Bags或者multisets（无序的集合，可能包含重复元素）应该直接实现这个接口。
 * 
 * <p>所有通用集合实现类（通常实现Collections的子接口之一），应该提供两个标准的构造器：
 * 一个无参构造器，创建一个空的集合，
 * 一个有着单一的类型为Collection的参数的构造器，创建一个集合，里面的元素与参数的相同。
 * 实际上，后一个构造器允许用户复制任何集合，生成一个与需要实现类型相同的集合。
 * 没有办法强制这种约定（因为接口不能含有构造器），但是Java平台库中的所有通用集合实现都遵守这种约定。
 * 
 * <p>这个接口包含破坏性的方法，即，修改其操作所在集合的方法，
 * 如果集合不支持这个操作，会抛出UnsupportedOperationException。
 * 如果是这种情况，如果调用方法对集合没有影响，这些方法可以抛出UnsupportedOperationException，但不是必须要抛出这个错误。
 * 例如，在一个不可变的集合上调用addAll(Collection)方法，如果被加入的集合是空的，可以，但不是必须要抛出这个错误
 * 
 * <p>一些集合的实现可能对它们包含的元素有限制。例如，一些实现禁止空元素，一些对元素的类型做限制。
 * 试图添加不符合条件的元素会抛出未检查错误，通常是NullPointerException或ClassCastException。
 * 试图查询一个不符合条件的元素可能抛出一个错误，或者通常可以返回false。
 * 有些实现会展示前一个行为，或展示后一个行为。
 * 更通常地，尝试对不符合条件的元素进行操作，而该元素的完成不会导致元素插入不进集合，
 * 这可能导致抛出错误，也可能会成功，都取决于实现。
 * 在这个接口的规范中，这种异常被标记为可选的。
 * 
 * <p>由每个集合决定它自己的同步策略。
 * 在实现缺乏更强的保证性的情况下，调用有一个线程操纵的集合的任何方法，可能导致未定义的行为。
 * 这包含直接调用方法，将集合传递给可能执行调用的方法，使用一个已经存在的iterator来检查这个集合
 * 
 * <p>在集合框架中，许多方法的定义与equals(Object)方法相关。
 * 例如，contains(Object)的规范称：当且仅当集合包含至少一个元素<tt>(o==null ? e==null : o.equals(e))</tt>，返回true。
 * 这样的规范不应该被解释为对所有非空元素调用o.equals(e)方法。
 * 实现可以自由地进行优化，来避免调用equals方法，例如一开始比较两个元素的hashcode
 * （hashCode()规范保证两个不同的对象有着不同的hashcode）
 * 更一般地说，各种集合框架接口的实现可以在实现者认为合适的地方自由地利用底层对象方法的指定行为。
 *
 * <p> 一些集合的行为，执行对集合的递归遍历可能会失败，自引用的实例可能直接或间接包含自身。
 * 这包括{@code clone()}, {@code equals()}, {@code hashCode()} 和 {@code toString()}方法。
 * 实现可能选择性地处理自引用场景，尽管大多数实现不会这样做。
 *
 * <p> 默认方法的实现不适用与任何同步协议。如果一个Collection实现有一个指定的同步策略，
 * 他必须覆盖默认的实现来实现该协议。
 *
 *
 * @param <E> the type of elements in this collection
 *
 * @author  Josh Bloch
 * @author  Neal Gafter
 * @see     Set
 * @see     List
 * @see     Map
 * @see     SortedSet
 * @see     SortedMap
 * @see     HashSet
 * @see     TreeSet
 * @see     ArrayList
 * @see     LinkedList
 * @see     Vector
 * @see     Collections
 * @see     Arrays
 * @see     AbstractCollection
 * @since 1.2
 */

public interface Collection<E> extends Iterable<E> {
    // 查询操作

    /**
     * 返回集合中元素的数量。如果集合包含超过Integer.MAX_VALUE的元素，返回Integer.MAX_VALUE
     *
     * @return the number of elements in this collection
     */
    int size();

    /**
     * 如果集合不包含任何元素，返回true
     *
     * @return <tt>true</tt> if this collection contains no elements
     */
    boolean isEmpty();

    /**
     * 如果集合包含指定元素，返回true。
     * 更正式地，当且仅当集合至少有一个这样的元素时，返回true。
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
     *
     * @param o element whose presence in this collection is to be tested
     * @return <tt>true</tt> if this collection contains the specified
     *         element
     * @throws ClassCastException 如果指定元素与集合不兼容，可选
     *         (<a href="#optional-restrictions">optional</a>)
     * @throws NullPointerException 如果指定元素为null，并且集合不允许空元素，可选
     *         (<a href="#optional-restrictions">optional</a>)
     */
    boolean contains(Object o);

    /**
     * 返回一个覆盖这个集合所有元素的iterator。
     * 不保证元素返回的顺序（除非集合是一些提供保证的类的实例）
     *
     * @return an <tt>Iterator</tt> over the elements in this collection
     */
    Iterator<E> iterator();

    /**
     * 返回一个包含这个集合所有元素的数组。
     * 如果集合保证由它的iterator返回的元素的顺序，这个方法必须以同样的顺序返回这些元素。
     *
     * <p>返回的数组是安全的，因为集合没有维持对它的引用
     * （换言而之，这个方法必须分配一个新的数组，即使集合内部已经有一个数组了）。
     * 因此调用者修改返回的数组是安全的。
     *
     * <p>这个方法是基于数组和基于集合的API之间的桥梁。
     *
     * @return an array containing all of the elements in this collection
     */
    Object[] toArray();

    /**
     * <p>返回一个包含这个集合所有元素的数组。
     * 返回的数组的运行时类型是指定数组的烈性。
     * 如果集合适合这个指定的数组的大小，她就在里面返回。
     * 否则，创建一个新数组，类型为指定数组的运行时类型，大小为这个集合的大小。
     * 
     * <p>如果该集合适应指定的数组，有着剩余的空间（数组比集合有更多的元素），
     * 数组中的元素在集合的末尾的，被设置为null。
     * （如果调用者知道集合确实没有任何null元素，这才有助于决定集合的长度）
     * 
     * <p>如果集合保证由它的iterator返回的元素的顺序，这个方法必须以同样的顺序返回这些元素。
     * 
     * <p>像toArray()方法，这个方法作为基于数组和基于集合的API之间的桥梁。
     * 此外，这个方法允许对输出的数组的运行时类型做出精确的控制。
     * 在某些情况下，可能有助于减少分配的成本。
     * 
     * <p>假设x是一个只能包含string的集合。
     * 下面的代码能用于将集合放入一个新分配的string数组。
     * 
     *
     * <pre>
     *     String[] y = x.toArray(new String[0]);</pre>
     *
     * 注意：toArray(new Object[0])等价于toArray()的功能
     *
     * @param <T> the runtime type of the array to contain the collection
     * @param a the array into which the elements of this collection are to be
     *        stored, if it is big enough; otherwise, a new array of the same
     *        runtime type is allocated for this purpose.
     * @return an array containing all of the elements in this collection
     * @throws ArrayStoreException 如果指定数组的运行时类型不是集合中每个元素的运行时类型的超类
     * @throws NullPointerException 如果指定数组为空
     */
    <T> T[] toArray(T[] a);

    // 修改操作

    /**
     * <p>保证集合中包含指定的元素（可选的操作）。
     * 当集合因此而改变，返回true。（如果集合不允许重复，而且已经包含指定元素，返回false）。
     * 
     * <p>支持此操作的集合可能会限制加入到集合的元素。
     * 尤其是，一些集合拒绝添加null元素，一些对元素的类型做限制。
     * 集合类应该明确地在他们的文档中，指定对可以添加的元素，做出哪些限制。
     * 
     * <p>如果结合拒绝添加一个特别的元素，而不是因为他已经包含了这个元素，
     * 他必须抛出一个异常（而不是返回false）。
     * 这保留了集合在调用返回后始终包含指定元素的不变性。
     * 
     *
     * @param e element whose presence in this collection is to be ensured
     * @return <tt>true</tt> if this collection changed as a result of the
     *         call
     * @throws UnsupportedOperationException 如果这个集合不支持add操作
     * @throws ClassCastException 如果指定元素的类，拒绝它被加入到这个集合
     * @throws NullPointerException 如果指定元素为null，而且集合不允许null元素
     * @throws IllegalArgumentException 如果元素的一些属性，拒绝它被加入到这个集合
     * @throws IllegalStateException 如果由于插入限制，元素此时不能被加入集合
     */
    boolean add(E e);

    /**
     * 如果指定元素存在，从集合中移除指定元素（可选的操作）。
     * 更正式地说，如果集合包含一个或多个这样的元素，就移除一个这样的元素 ，
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
     * 如果集合包含指定元素，返回true。（如果集合因为调用而改变，返回true）
     *
     * @param o element to be removed from this collection, if present
     * @return <tt>true</tt> if an element was removed as a result of this call
     * @throws ClassCastException if the type of the specified element
     *         is incompatible with this collection
     *         (<a href="#optional-restrictions">optional</a>)
     * @throws NullPointerException if the specified element is null and this
     *         collection does not permit null elements
     *         (<a href="#optional-restrictions">optional</a>)
     * @throws UnsupportedOperationException if the <tt>remove</tt> operation
     *         is not supported by this collection
     */
    boolean remove(Object o);


    // 批量操作

    /**
     * 如果集合包含指定集合中所有的元素，返回true
     *
     * @param  c collection to be checked for containment in this collection
     * @return <tt>true</tt> if this collection contains all of the elements
     *         in the specified collection
     * @throws ClassCastException if the types of one or more elements
     *         in the specified collection are incompatible with this
     *         collection
     *         (<a href="#optional-restrictions">optional</a>)
     * @throws NullPointerException if the specified collection contains one
     *         or more null elements and this collection does not permit null
     *         elements
     *         (<a href="#optional-restrictions">optional</a>),
     *         or if the specified collection is null.
     * @see    #contains(Object)
     */
    boolean containsAll(Collection<?> c);

    /**
     * 将指定集合的所有元素加入到这个集合（可选操作）。
     * 当执行操作时，如果修改指定集合，操作的结果未知。
     * （这意味着，如果如果指定集合是这个集合，而且集合是非空的，调用的结果未知）
     *
     * @param c collection containing elements to be added to this collection
     * @return <tt>true</tt> if this collection changed as a result of the call
     * @throws UnsupportedOperationException if the <tt>addAll</tt> operation
     *         is not supported by this collection
     * @throws ClassCastException if the class of an element of the specified
     *         collection prevents it from being added to this collection
     * @throws NullPointerException if the specified collection contains a
     *         null element and this collection does not permit null elements,
     *         or if the specified collection is null
     * @throws IllegalArgumentException if some property of an element of the
     *         specified collection prevents it from being added to this
     *         collection
     * @throws IllegalStateException if not all the elements can be added at
     *         this time due to insertion restrictions
     * @see #add(Object)
     */
    boolean addAll(Collection<? extends E> c);

    /**
     * 删除这个集合中，所有已经包含在指定集合的元素（可选操作）。
     * 在这次调用后，这个集合不会与指定集合包含相同的元素
     *
     * @param c collection containing elements to be removed from this collection
     * @return 如果集合在调用中，被改变了，返回true
     * @throws UnsupportedOperationException if the <tt>removeAll</tt> method
     *         is not supported by this collection
     * @throws ClassCastException if the types of one or more elements
     *         in this collection are incompatible with the specified
     *         collection
     *         (<a href="#optional-restrictions">optional</a>)
     * @throws NullPointerException if this collection contains one or more
     *         null elements and the specified collection does not support
     *         null elements
     *         (<a href="#optional-restrictions">optional</a>),
     *         or if the specified collection is null
     * @see #remove(Object)
     * @see #contains(Object)
     */
    boolean removeAll(Collection<?> c);

    /**
     * 移除集合中所有满足给定断言（predicate）的元素。
     * 在遍历时或者执行断言时的错误，被转发给调用者。
     * 
     * <p>默认的实现使用了iterator遍历了集合中所有的元素。
     * 使用iterator.remove()来移除每个匹配的元素（filter返回true，移除元素）。
     * 如果集合的iterator不支持移除操作，在第一个匹配的元素时，抛出UnsupportedOperationException
     *
     * @param filter a predicate which returns {@code true} for elements to be
     *        removed
     * @return {@code true} 如果有元素被移除了
     * @throws NullPointerException if the specified filter is null
     * @throws UnsupportedOperationException if elements cannot be removed
     *         from this collection.  Implementations may throw this exception if a
     *         matching element cannot be removed or if, in general, removal is not
     *         supported.
     * @since 1.8
     */
    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
            	//如果filter返回true，则移除这个元素
                each.remove();
                removed = true;
            }
        }
        return removed;
    }

    /**
     * 只保留指定集合包含的元素。（可选操作）。
     * 换言而之，移除所有不被指定集合包含的元素。
     *
     * @param c collection containing elements to be retained in this collection
     * @return <tt>true</tt> if this collection changed as a result of the call
     * @throws UnsupportedOperationException if the <tt>retainAll</tt> operation
     *         is not supported by this collection
     * @throws ClassCastException if the types of one or more elements
     *         in this collection are incompatible with the specified
     *         collection
     *         (<a href="#optional-restrictions">optional</a>)
     * @throws NullPointerException if this collection contains one or more
     *         null elements and the specified collection does not permit null
     *         elements
     *         (<a href="#optional-restrictions">optional</a>),
     *         or if the specified collection is null
     * @see #remove(Object)
     * @see #contains(Object)
     */
    boolean retainAll(Collection<?> c);

    /**
     * 移除集合中所有的元素（可选操作）。这个方法返回后，集合为空。
     *
     * @throws UnsupportedOperationException if the <tt>clear</tt> operation
     *         is not supported by this collection
     */
    void clear();


    // 比较和计算哈希

    /**
     * <p>将指定对象与这个集合进行相等性的比较。
     * 
     * <p>然而Collection接口没有对Object.equals增加规定，
     * 直接实现Collection接口（即，创建一个是Collection类，但不是一个set或List）的程序员，
     * 必须注意是否覆盖Object.equals。没有必要这样做，最简单的行为是依赖Object的实现，
     * 但是实现者可能希望一个值比较而不是默认的引用比较。
     * （List和Set接口要求这样的值比较）
     *
     * (By the same logic, it is not possible
     * to write a class that correctly implements both the <tt>Set</tt> and
     * <tt>List</tt> interfaces.)
     * 
     * 通常对Object.equals方法的约定是equals必须是对称的（换言而之a.equals(b) == b.equals(a)）。
     * List.equals和Set.equals的约定是list仅仅对其他list相等，sets仅仅对其他sets相等.
     * 因此，一个实现Collection接口，但不是List或Set接口的类的equals方法，必须与其他list或set比较时，返回false。
     * 
     *
     * @param o object to be compared for equality with this collection
     * @return <tt>true</tt> if the specified object is equal to this
     * collection
     *
     * @see Object#equals(Object)
     * @see Set#equals(Object)
     * @see List#equals(Object)
     */
    boolean equals(Object o);

    /**
     * 返回这个集合的hashcode。然而Collection接口没有对Object.hashCode增加规定。
     * 程序员应该注意：任何覆盖Object.equals方法的类，应该也覆盖Object.hashCode方法，
     * 来满足对Object.hashCode的通常约定。
     * 尤其是c1.equals(c2)隐含着c1.hashCode()==c2.hashCode()
     *
     * @return the hash code value for this collection
     *
     * @see Object#hashCode()
     * @see Object#equals(Object)
     */
    int hashCode();

    /**
     * <p>创建一个覆盖这个集合的spliterator。
     * 
     * <p>实现应该文档化，由这个spliterator报告的特征值。
     * 如果spliterator报告是SIZED，并且集合没有元素，这样的特征值不需要被报告。
     * 
     * <p>默认的实现应该被覆盖，子类应该返回一个更有效的spliterator。
     * 为了保持stream()和parallelStream()方法的预期懒惰行为，
     * spliterator应该有特征IMMUTABLE或CONCURRENT或是迟绑定的。
     * 如果这三个都不实用，覆盖的类应该表达spliterator的文档化的绑定和结构干扰的策略，
     * 并且应该覆盖stream()和parallelStream()方法来创建使用这个spliterator的Supplier的流。
     * 
     * <pre>{@code
     *     Stream<E> s = StreamSupport.stream(() -> spliterator(), spliteratorCharacteristics)
     * }</pre>
     * <p>
     * 
     * 这种要求，保证由stream()和parallelStream()方法产生的流会反映集合的内容，作为最终流操作的初始。
     *
     * <p>默认实现从集合的iterator创建了一个迟绑定的spliterator。
     * 这个spliterator继承集合的iterator的快速失败属性。
     *
     * <p>创建的spliterator额外报告SUBSIZED
     *
     * <p>如果一个spliterator什么元素都没有覆盖，那么报告额外的特征值，除了SIZED和SUBSIZED之外，
     * 不能帮助用户去控制，特殊化或者简化计算。
     * 然而，这确实能够共享使用一个不可变的，空的spliterator实例，对于空的集合。
     * 让客户决定是否这样的spliterator没有覆盖元素。
     *
     * @return a {@code Spliterator} over the elements in this collection
     * @since 1.8
     */
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, 0);
    }

    /**
     * 返回一个以该集合为源的序列流。
     * 当spliterator()不能返回一个是IMMUTABLE，CONCURRENT或者迟绑定的spliterator，方法应该被覆盖。
     * 默认的实现创建一个以该集合为源的序列流
     *
     * @return a sequential {@code Stream} over the elements in this collection
     * @since 1.8
     */
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }

    /**
     * 返回一个以该集合为源的可能是并发的流。允许这个方法返回一个序列流。
     * 当spliterator()不能返回一个是IMMUTABLE，CONCURRENT或者迟绑定的spliterator，方法应该被覆盖。
     * 默认的实现创建一个以该集合为源的并发流
     *
     * @return a possibly parallel {@code Stream} over the elements in this
     * collection
     * @since 1.8
     */
    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}
